package main

import (
	"bytes"
	"embed"
	"encoding/json"
	"fmt"
	"io"
	"math/rand"
	"os"
	"path/filepath"
	"pic-golang/img_uploader"
	"strings"
)

//go:embed config
var configs embed.FS

const ConfigDir = "config"

func chDir() {
	executable, _ := os.Executable()
	abs, _ := filepath.Abs(executable)
	_ = os.Chdir(filepath.Dir(abs))
}

/*
*
随机获取一个配置作为图床，以均摊上传频率，注意程序不会检查配置是否可用，所以请自行保证其有效性，后续将对randomUploader进行排序
*/
func getRandomUploader() (img_uploader.ImgUploader, error) {
	chDir()
	dir, err := os.ReadDir(ConfigDir)
	if err != nil || len(dir) == 0 {
		if err != nil { // 尝试重新创建目录然后
			_ = os.Mkdir(ConfigDir, 0755)
		}
		dir, err = os.ReadDir(ConfigDir) // 再次读取
		if err != nil {                  // 如果依然无法正常读取，则报错退出
			return nil, err
		}
		embedDir, _ := configs.ReadDir(ConfigDir)
		for _, file := range embedDir { // 读取内置配置文件，并写入外部目录
			err := func() error {
				config, _ := configs.ReadFile(ConfigDir + "/" + file.Name())
				target, err := os.OpenFile(ConfigDir+"/"+file.Name(), os.O_RDWR|os.O_CREATE, 0755)
				if err != nil {
					return err
				}
				defer target.Close()
				_, err = io.Copy(target, bytes.NewReader(config))
				if err != nil {
					return err
				}
				return nil
			}()
			if err != nil {
				return nil, err
			}
		}
		dir, _ = os.ReadDir(ConfigDir) // 再次读取，确保能获取到写入的文件
	}
	var confs []string

	for _, config := range dir {
		if strings.HasSuffix(config.Name(), ".sxcu") {
			confs = append(confs, config.Name())
		}
	}
	randomConfig := confs[rand.Intn(len(confs))]
	conf, err := os.ReadFile(ConfigDir + "/" + randomConfig)
	if err != nil {
		return nil, err
	}
	var uploader = &img_uploader.GenericImgUploader{}
	err = json.Unmarshal(conf, uploader)
	if err != nil {
		return nil, err
	}
	if upl, ok := img_uploader.ExtUploader[uploader.RequestURL]; ok { // 对有特定行为的上传器进行二次包装
		upl.SetUploader(uploader)
		return upl, nil
	}
	return uploader, nil
}

func main() {

	if len(os.Args) < 2 {
		fmt.Println("error: the image path is empty")
		return
	}
	uploader, err := getRandomUploader()
	if err != nil {
		fmt.Println(err, uploader)
		return
	}
	err = uploader.IsCookieValid()
	if err != nil {
		fmt.Println(err, uploader)
		return
	}

	uploader.Input(os.Args[1:])

	err = uploader.Transformer()
	if err != nil {
		fmt.Println(err, uploader)
		return
	}

	err = uploader.Upload()
	if err != nil {
		fmt.Println(err, uploader)
		return
	}

	results := uploader.GetUploadResults()
	for _, result := range results {
		fmt.Println(result)
	}
}
